import bge
import Rasterizer
#import GameLogic
from mathutils import Vector
import GameLogic


cam = bge.logic.getCurrentScene().objects["camera"]
camPos = cam.parent
camBase = camPos.parent
camOrb = bge.logic.getCurrentScene().objects["camOrb"]

mouse = cam.sensors["Mouse"]
wheelUp = cam.sensors["mouseWheelUp"]
wheelDown = cam.sensors["mouseWheelDown"]
wheelButton = cam.sensors["mouseWheelButton"]

sensitivity = cam["sensitivity"]
invertX = cam["invertX"]
invertY = cam["invertY"]

windowHeight = Rasterizer.getWindowHeight()
windowWidth = Rasterizer.getWindowWidth()

def findXYIntercept(rayOut, offset):
	rayOut = offset - rayOut
	
	if offset[0] - rayOut[0] != 0:
		m = (offset[2] - rayOut[2]) / (offset[0] - rayOut[0])
		b = offset[2] - (m * offset[0])
		
		xIntercept = -b / m
	
	else:
		xIntercept = offset[0]
	
	if offset[1] - rayOut[1] != 0:
		m = (offset[2] - rayOut[2]) / (offset[1] - rayOut[1])
		b = offset[2] - (m * offset[1])
		
		yIntercept = -b / m
	
	else:
		yIntercept = offset[1]
	
	return Vector([xIntercept,yIntercept, 0.0])
	
def findMouseLocation():
	rayOut = Vector(mouse.rayDirection)
	offset = Vector(cam.worldPosition)
	
	return findXYIntercept(rayOut, offset)

def findOrbLocation():
	rayOut = Vector(cam.getScreenVect(.5, .5))
	offset = Vector(cam.worldPosition)
	
	return findXYIntercept(rayOut, offset)

def zoom():
	minZoom = 20
	maxZoom = 1500
	zoomSpeedMult = .10
	distance = camPos.worldPosition[2]
	
	zoomSpeed = zoomSpeedMult * distance
	
	if distance > minZoom and wheelUp.positive:
		zoom = -zoomSpeed
		cam["zooming"] = True
		
	elif distance < maxZoom and wheelDown.positive:
		zoom = zoomSpeed
		cam["zooming"] = True
		
	else:
		zoom = 0.0
		cam["zooming"] = False
	
	mouseLoc = findMouseLocation()
	vecTo = (Vector(cam.worldPosition) - mouseLoc).normalize() * zoom
	camPos.applyMovement(vecTo)
	camOrb.worldPosition = findOrbLocation()

	GameLogic.zoomlevel = camPos.position[2] #jplur needs this hook
	
def pan():
	distance = camPos.worldPosition[2]
	panDist = windowHeight/cam["panMargin"]
	panSpeedMult = distance * sensitivity * .005
	
	if not cam["orbiting"]:# and not cam["zooming"]:
		#print("not orbing!!")
		# mouse is in bounds #
		if mouse.position[0] > 0 and mouse.position[0] < windowWidth and mouse.position[1] > 0 and mouse.position[1] < windowHeight:
			cam["panning"] = True
			
			# movement in X #
			if mouse.position[0] <= panDist:
				xMove = -(panDist - mouse.position[0]) * panSpeedMult
				
			elif mouse.position[0] >= windowWidth - panDist:
				xMove = (panDist - (windowWidth - mouse.position[0])) * panSpeedMult
			
			else:
				xMove = 0.0

			# movement in Y #
			if mouse.position[1] <= panDist:
				yMove = (panDist - mouse.position[1]) * panSpeedMult

			elif mouse.position[1] >= windowHeight - panDist:
				yMove = (panDist - (windowHeight - mouse.position[1])) * -panSpeedMult

			else:
				yMove = 0.0

			camBase.applyMovement([xMove, yMove, 0], True)
			
			
			if xMove == 0 and yMove ==0:
				cam["panning"] = False
	else:
		camBase.applyMovement([0, 0, 0], True)
		cam["panning"] = False
		
def orbit():
	maxAngle = 1.3962634 # About 80 degrees
	minAngle = 0.523598776 # About 30 degrees
	orbMult = .05
	
	if not cam["zooming"]:
		def getMouseOffset():
			x = (windowWidth//2 - mouse.position[0]) * sensitivity * invertX * orbMult
			y = (windowHeight//2 - mouse.position[1]) * sensitivity * invertY * orbMult
			
			return([x,y])
		
		status = mouse.getButtonStatus(bge.events.MIDDLEMOUSE)
		#camPos.setParent(camOrb)
		if status == bge.logic.KX_INPUT_JUST_ACTIVATED:
			#camOrb.worldPosition = [findOrbLocation[0], findOrbLocation[1], 0]
			Rasterizer.showMouse(False)
			cam["lastMPos"] = mouse.position
			Rasterizer.setMousePosition(windowWidth//2, windowHeight//2)
			camPos.setParent(camOrb)
			cam["orbiting"] = True
		elif status == bge.logic.KX_INPUT_ACTIVE:
			pos = getMouseOffset()
			camOrb.applyRotation([0, 0, pos[0]], 0)
			camBase.applyRotation([0, 0, pos[0]], 0)
			
			angle = Vector([0, 0, 1]).angle(Vector(camPos.worldPosition)- Vector(camOrb.worldPosition))
			print(angle)
			
			if angle > maxAngle and pos[1] < 0:
				camOrb.applyRotation([pos[1], 0, 0], 1)
			elif angle < minAngle and pos[1] > 0:
				camOrb.applyRotation([pos[1], 0, 0], 1)
			elif angle < maxAngle and angle > minAngle:
				camOrb.applyRotation([pos[1], 0, 0], 1)

			Rasterizer.setMousePosition(windowWidth//2, windowHeight//2)
			cam["orbiting"] = True
		elif status == bge.logic.KX_INPUT_JUST_RELEASED:
			camPos.setParent(camBase)
			Rasterizer.setMousePosition(cam["lastMPos"][0], cam["lastMPos"][1])
			Rasterizer.showMouse(True)
			cam["orbiting"] = True
		else:
			cam["orbiting"] = False
	#print (cam["orbiting"])